﻿//#define _CRT_SECURE_NO_WARNINGS
//
////namespace czy
////{
////	template<class T>
////	class shared_ptr
////	{
////	public:
////		T* operator->()
////		{
////			return _ptr;
////		}
////		T& operator*()
////		{
////			return *(_ptr);
////		}
////		shared_ptr(T*ptr=nullptr):_ptr(ptr),_count(new int(1))
////		{}
////		~shared_ptr()
////		{
////			if (--(*_count) == 0)
////			{
////				delete _ptr;
////				_ptr = nullptr;
////			}
////		}
////		shared_ptr(const shared_ptr<T>& ptr)
////		{
////			(*ptr._count)++;
////			_ptr = ptr._ptr;
////			_count = ptr._count;
////
////		}
////		//赋值
////		//this=ptr
////		shared_ptr<T>& operator=(const shared_ptr<T>& ptr)
////		{
////			if (ptr._ptr != _ptr)
////			{
////				if (--(*_count) == 0)
////				{
////					delete _ptr;
////					_ptr = nullptr;
////					delete _count;
////				}
////				_ptr = ptr._ptr;
////				_count = ptr._count;
////				++(*_count);
////			}
////			return *this;
////		}
////	private:
////		T* _ptr;
////		int* _count;//这里不用static是因为我们要保证指向统一资源的智能指针的计数是一样的；
////		//而不是所有的智能指针都是一样的
////	};
////}
////int main()
////{
////	czy::shared_ptr<Date>p1(new Date);
////	czy::shared_ptr<Date>p2(p1);
////	czy::shared_ptr<Date>p3(p2);
////	czy::shared_ptr<Date>p4(new Date);
////	p2 = p4;
////
////
////	czy::shared_ptr<Date>u1(new Date);
////	czy::shared_ptr<Date>u2(u1);
////	czy::shared_ptr<Date>u3(u2);
////	czy::shared_ptr<Date>u4(new Date);
////
////
////	return 0;
////}
//
//
//#include<memory>
//#include<functional>
//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 2024, int month = 12, int day = 12) :_year(year), _month(month), _day(day)
//	{
//	}
//	//不显示实现初始化列表时会看成员变量是否给了默认值有的话就是用默认值没有就是随机值
//	//默认生成的初始化列表会去看成员函数会否被赋予初值，接着执行函数内的语句
//
//	~Date()
//	{
//		cout << "~date" << endl;
//	}
//	int _year;
//	int _month;
//	int _day;
//};
//
//
//
//namespace czy
//{
//	template<class T>
//	class shared_ptr
//	{
//	public:
//		T* operator->()
//		{
//			return  _ptr;
//		}
//		T& operator*()
//		{
//			return *_ptr;
//		}
//		//构造函数
//		explicit shared_ptr(T* ptr = nullptr) :_ptr(ptr), _count(new int(1))
//		{
//		}
//
//
//		//提供一个有删除器的构造
//		//删除器是一个可以调用的对象并且是返回值void参数为T*的一个可调用对象
//		template<class D>
//		shared_ptr(T*ptr,D del):_ptr(ptr),_count(new int(1)),_del(del)
//		{
//		}
//
//		//析构函数
//		~shared_ptr()
//		{
//			if (--(*_count) == 0)
//			{
//				/*delete ptr;*/
//				_del(_ptr);
//				delete _count;
//				/*ptr = nullptr;
//				*/
//				_count = nullptr;
//			}
//		}
//		//拷贝构造函数(this(ptr))
//		shared_ptr(const shared_ptr<T>& ptr)
//		{
//			(*ptr._count)++;
//			_ptr = ptr._ptr;
//			_count = ptr._count;
//
//		}
//		//赋值函数
//		//this=ptr
//		shared_ptr<T>& operator=(const shared_ptr<T>ptr)
//		{
//			if (_ptr != ptr._ptr)
//			{
//				if (--(*_count) == 0)
//				{
//					_del(_ptr);
//					delete _count;
//					_count = nullptr;
//
//				}
//				(*ptr._count)++;
//				_ptr = ptr._ptr;
//				_count = ptr._count;
//			}
//			return *this;
//		}
//
//	private:
//		T* _ptr;
//		int* _count;
//		function<void(T*)> _del = [](T* ptr) {delete ptr; ptr = nullptr; };
//	};
//}
//
////int main()
////{
////    czy::shared_ptr<Date> sp1(new Date(2025,12,12));
////    czy::shared_ptr<Date> sp2(sp1);
////    // 拷贝构造
////    czy::shared_ptr<Date> sp3 = sp2;
////
////    czy::shared_ptr<Date> sp4(new Date(2023,12,12));
////
////    sp1->_year++;
////    sp3->_month++;
////
////    // 赋值拷贝
////    //sp1 = sp4;
////    sp4 = sp4;
////    sp1 = sp2;
////	sp2 = sp4;
////	return 0;
////}
//
//class Fclose
//{
//public:
//	void operator()(FILE* ptr)
//	{
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//	}
//};
//
//template<class T>
//void DeleteArrayFunc(T* ptr)
//{
//	delete[] ptr;
//}
////int main()
////{
////    czy::shared_ptr<Date> sp1(new Date);
////
////    // 定制删除器 都可以，相对建议lambda
////    czy::shared_ptr<Date> sp3(new Date[10], [](Date* ptr) {delete[] ptr; });
////}
//
////int main()
////{
////    std::shared_ptr<Date> sp1(new Date);
////    std::shared_ptr<Date[]> sp2(new Date[10]);
////
////    // 定制删除器 都可以，相对建议lambda
////    std::shared_ptr<Date> sp3(new Date[10], [](Date* ptr) {delete[] ptr; });
////    std::shared_ptr<Date> sp4(new Date[5], DeleteArrayFunc<Date>);
////
////    std::shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
////    shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr) {
////        //cout << "fclose:" << ptr << endl;
////        fclose(ptr);
////        });
////
////    std::unique_ptr<Date> up1(new Date);
////    std::unique_ptr<Date[]> up2(new Date[10]);
////    // 定制删除器 建议仿函数
////    std::unique_ptr<FILE, Fclose> up3(fopen("Test.cpp", "r"));
////	//decltype用来自动推导类型
////    auto fcloseFunc = [](FILE* ptr) {fclose(ptr); };
////    std::unique_ptr<FILE, decltype(fcloseFunc)> up4(fopen("Test.cpp", "r"), fcloseFunc);
////
////    return 0;
////}
//
////int main()
////{
////    std::shared_ptr<Date> sp1(new Date(2024, 9, 11));
////    shared_ptr<Date> sp2 = make_shared<Date>(2024, 9, 11);
////    shared_ptr<Date> sp4;
////
////    // if (sp1.operator bool())
////    if (sp1)
////        cout << "sp1 is not nullptr" << endl;
////
////    //if (!sp4)
////    if (!sp4.operator bool())
////        cout << "sp4 is nullptr" << endl;
////
////    //shared_ptr<Date> sp5 = new Date(2024, 9, 11);
////    //unique_ptr<Date> sp6 = new Date(2024, 9, 11);
////
////    return 0;
////}
//
//
//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//void Func()
//{
//	// 这⾥可以看到如果发⽣除0错误抛出异常，另外下⾯的array和array2没有得到释放。
//	// 所以这⾥捕获异常后并不处理异常，异常还是交给外⾯处理，这⾥捕获了再重新抛出去。
//	// 但是如果array2new的时候抛异常呢，就还需要套⼀层捕获释放逻辑，这⾥更好解决⽅案
//	// 是智能指针，否则代码太戳了
//	int* array1 = new int[10];
//	int* array2 = new int[10]; // 抛异常呢
//	try
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Divide(len, time) << endl;
//	}
//	catch (...)
//	{
//		cout << "delete []" << array1 << endl;
//		cout << "delete []" << array2 << endl;
//		delete[] array1;
//		delete[] array2;
//		throw; // 异常重新抛出，捕获到什么抛出什么
//	}
//	// ...
//	cout << "delete []" << array1 << endl;
//	delete[] array1;
//	cout << "delete []" << array2 << endl;
//	delete[] array2;
//}
////int main()
////{
////	try
////	{
////		Func();
////	}
////	catch (const char* errmsg)
////	{
////		cout << errmsg << endl;
////	}
////	catch (const exception& e)
////	{
////		cout << e.what() << endl;
////	}
////	catch (...)
////	{
////		cout << "未知异常" << endl;
////	}
////	return 0;
////}
//
//namespace czy
//{
//	template<class T>
//	class auto_ptr
//	{
//	public:
//		auto_ptr(T* ptr)
//			:_ptr(ptr)
//		{}
//		auto_ptr(auto_ptr<T>& sp)
//			:_ptr(sp._ptr)
//		{
//			// 管理权转移
//			sp._ptr = nullptr;
//		}
//		auto_ptr<T>& operator=(auto_ptr<T>& ap)
//		{
//			// 检测是否为⾃⼰给⾃⼰赋值
//			if (this != &ap)
//			{
//				// 释放当前对象中资源
//				if (_ptr)
//					delete _ptr;
//				// 转移ap中资源到当前对象中
//				_ptr = ap._ptr;
//				ap._ptr = NULL;
//			}
//			return *this;
//		}
//		~auto_ptr()
//		{
//			if (_ptr)
//			{
//				cout << "delete:" << _ptr << endl;
//				delete _ptr;
//			}
//		}
//		T& operator*()
//		{
//			return *_ptr;
//		}
//		T* operator->()
//		{
//			return _ptr;
//		}
//	private:
//		T* _ptr;
//		
//	};
//
//
//	template<class T>
//	class unique_ptr
//	{
//	public:
//		explicit unique_ptr(T* ptr)
//			:_ptr(ptr)
//		{}
//		~unique_ptr()
//		{
//			if (_ptr)
//			{
//				cout << "delete:" << _ptr << endl;
//				delete _ptr;
//			}
//		}
//		// 像指针⼀样使⽤
//		T& operator*()
//		{
//			return *_ptr;
//		}
//		T* operator->()
//		{
//			return _ptr;
//		}
//		unique_ptr(const unique_ptr<T>& sp) = delete;
//		unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;
//	private:
//		T* _ptr;
//	};
//}
//
//
//struct ListNode
//{
//	int _data;
//	std::shared_ptr<ListNode> _next;
//	std::shared_ptr<ListNode> _prev;
//	// 这⾥改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
//	// 不增加n2的引⽤计数，不参与资源释放的管理，就不会形成循环引⽤了
//	/*std::weak_ptr<ListNode> _next;
//	std::weak_ptr<ListNode> _prev;*/
//	~ListNode()
//	{
//		cout << "~ListNode()" << endl;
//	}
//};
//int main()
//{
//	std::shared_ptr<string> sp1(new string("111111"));
//	std::shared_ptr<string> sp2(sp1);
//	std::weak_ptr<string> wp = sp1;
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	// sp1和sp2都指向了其他资源，则weak_ptr就过期了
//	sp1 = make_shared<string>("222222");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	sp2 = make_shared<string>("333333");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	wp = sp1;
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	//std::shared_ptr<string> sp3 = wp.lock();
//	auto sp3 = wp.lock();
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	*sp3 += "###";
//	cout << *sp1 << endl;
//	return 0;
//}